 function Module()
{
 
	this.version = null;
	this.type = null;  //Possible values -> "fund" || "quote"
	this.quoteHistorySourceURL = null;
	this.quoteNameSourceURL = null;
	this.moduleHostURL = null;
	this.configuration = null;
	this.content = null;
 	this.id = null;
  
	this.investedValues= null;
  
	this.getLastInvestment = getLastInvestment;
	this.getFirstInvestment = getFirstInvestment;
	this.getInvestmentValue = getInvestmentValue;
	this.getTotalInvested = getTotalInvested;
	this.getPurchasedQuantity = getPurchasedQuantity;
  
	this.loadModuleProperties = null;
	this.checkModuleInitialized = null;
	this.printHowTo = null;
  
 	this.fireQuotationDataLoaded = null;
	
    
	// To be implemtned yet.. Regarding a new edit form approach 
	this.setModuleProperties = null;
}

function Fund()
{
  this.name="";
  this.quotes=new Array();
}

function Quote(symbol, percent)
{
  this.name ="";
  this.symbol = symbol;
  this.compositionPercent= percent;
  this.cotations = new Array();
  this.getCotation = getCotation;
  this.getLoadedCotationsQtd = getLoadedCotationsQtd;
}

function Cotation(date,value)
{
  this.date = date;
  this.value = value;
}

function InvestedValue(date, value)
{
  this.date = date;
  this.value = value;
  this.quotesData = new Array();
  this.addQuoteData = addQuoteData;

}



function QuoteData(_quote,_cotation, _addCotationIntoQuoteHistory)
{
  this.quote = _quote;
  this.cotation = _cotation;
  this.setPurchasedQuantity = setPurchasedQuantity;
  this.purchasedQuantity = 0;
  
  if(_addCotationIntoQuoteHistory == null)
  	_addCotationIntoQuoteHistory = true;
  
  if(_addCotationIntoQuoteHistory && (this.quote.getCotation(this.cotation.date)== null))
  {
  	this.quote.cotations.push(this.cotation);
  }
}

function Configuration()
{
  this.quoteHistorySourceURL = "";
  this.quoteNameSourceURL = "";
  this.moduleHostURL = "";
  this.chartURL = "";
  this.quoteURL = "";
  
  this.chart_timeDuration = 0;
  this.chart_timeUnit = null;
  
  this.history_numRecords = 0;
  this.history_percentBaseMode = "";
  this.history_percentBaseDate = null;
  this.thresholdBuy = 0;
  this.thresholdSell = 0;

}
  
    
function setPurchasedQuantity(_investedValue)
 {
 
  var realValue = _investedValue * this.quote.compositionPercent / 100;
  
  this.purchasedQuantity = realValue / this.cotation.value;
  
 }  
 
function addQuoteData(quote, cotation)
{
	var quoteData = new QuoteData(quote,cotation);
	quoteData.setPurchasedQuantity(this.value);
	this.quotesData.push(quoteData);
	return quoteData;
	
}

function getLastInvestment()
{
	var investedRes = null;
	var qtdInvestments = 0;
	var invested;
	
	if(this.investedValues!=null)
	{
		investedRes = this.investedValues[0];
		qtdInvestments = this.investedValues.length;
	}
	
	for( var  i=1;i<qtdInvestments;i++)
	{
		invested = this.investedValues[i];
		if(investedRes.date < invested.date)
		   investedRes = invested;
	}
	
	return investedRes;
	
}

function getFirstInvestment()
{
	var investedRes = this.investedValues[0];
	var invested;
	
	for( var  i=1;i<this.investedValues.length;i++)
	{
		invested = this.investedValues[i];
		if(investedRes.date > invested.date)
		   investedRes = invested;
	}
	
	return investedRes;
	
	
}

function getTotalInvested(_date)
{
	var val = 0;
	var i;
	if(_date==null)
		_date = new Date();
	
	for( i=0;i<this.investedValues.length;i++)
	{
		if(_date.getTime() >= this.investedValues[i].date.getTime())
		{
			val += this.investedValues[i].value;
		}
			
	}
	
	return val;
}



/**
 * 
 * @param {Object} _quoteSymbol
 * @param {Object} _date --> if _date ==null, this fucntion will return all the quantity until today 
 * otherwise it will load the quantity until this date
 * 
 */
function getPurchasedQuantity(_quoteSymbol, _date)
{
	var quantity = 0;
	var date;
	var invested;
	
	if(_date ==null)
		_date = new Date();
	
	date = getValidDate(_date);	
	
	for( var  i=0;i<this.investedValues.length;i++)
	{
		invested = this.investedValues[i];
		if(date.getTime() >= invested.date.getTime())
		{
			for( var j=0;j<invested.quotesData.length;j++)
			{
				if(invested.quotesData[j].quote.symbol==_quoteSymbol)
				{
					quantity += invested.quotesData[j].purchasedQuantity;
				}
			}
		}
		
	}
	
	return quantity;
}

function getInvestmentValue(_date)
{
	var finalValue = 0; //there is no cotation loaded for this date
	var cotation = null;
	var quantity;
	var date = getValidDate(_date);
	
	for( var i=0;i<this.fund.quotes.length;i++)
	{
		quantity = this.getPurchasedQuantity(this.fund.quotes[i].symbol, date);
		cotation = this.fund.quotes[i].getCotation(date);	
		if(cotation !=null)
			finalValue += quantity * cotation.value;
		else
			{
				finalValue = null;
				break;
			}
	}

	return finalValue;
}

function getCotation(_date)
{
	var cotationRes = null;
	for( var i=0;i<this.cotations.length; i++)
	{
		cotationRes = this.cotations[i];
		if(cotationRes.date.getTime() == _date.getTime()) return cotationRes;
	}
	
	return null;
}

/**
 * It is assumed that the array is sorted in a descrecent way by date
 * @param {Object} _quote
 * @param {Object} _dateIni
 * @param {Object} _dateFim
 */		
function getLoadedCotationsQtd(_dateIni, _dateFim)
{
	var recordsQtd = -1;
	var started = false;
	var cotation;
	
	for(var i=0;i<this.cotations.length;i++)
	{
		cotation = this.cotations[i];
		if(started) recordsQtd++;
		
		if(!started && (_dateFim.getTime()>= cotation.date.getTime()))
		{
			started = true;
			recordsQtd = 1;
		}
		
		if(_dateIni.getTime() == cotation.date.getTime() )
		{
			break;
		}
		
		if(_dateIni.getTime() > cotation.date.getTime() )
		{
			recordsQtd--;
			break;
		}
	}
	
	
	return recordsQtd;
	
}

